home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / c-part2 / 12579 < prev    next >
Encoding:
Text File  |  1996-08-05  |  4.2 KB  |  130 lines

  1. Path: lrz-muenchen.de!news
  2. From: watzka@stat.uni-muenchen.de (Kurt Watzka)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: Why does my program do this?
  5. Date: 1 Apr 1996 17:21:43 GMT
  6. Organization: Leibniz-Rechenzentrum, Muenchen (Germany)
  7. Distribution: world
  8. Message-ID: <4jp3b7$ja7@sparcserver.lrz-muenchen.de>
  9. References: <4jnln2$95j@dfw-ixnews3.ix.netcom.com>
  10. NNTP-Posting-Host: sun2.lrz-muenchen.de
  11.  
  12. ishky@ix.netcom.com(Andrew Heiz ) writes:
  13.  
  14. >Hi again,
  15.  
  16. >There have been so many helpful readers out there here is another
  17. >question for you.
  18.  
  19. >I've declared an 2 dimentional array:
  20.  
  21. >char scores[STUDENT][5];
  22.  
  23. >I am entering the scores in 2 for loops like this:
  24.  
  25. >    for (i=0; i <= students-1; i=i+1)
  26.  
  27. 1) Is "students" somehow related to "STUDENT"? If yes, why do you
  28.    present both?
  29.  
  30. 2) "i++" _is_ a common idiom  in C. Get used to it.
  31.  
  32. 3) A less common idiom, but quite useful for "looping over all
  33.    elements of an array of STUDENT elements is
  34.  
  35.    for (i = 0; i < STUDENT; i++)
  36.  
  37.    This is a question of style, but it makes the relation to
  38.    the number of elements in an array more obvious, imho.
  39.  
  40. >        {
  41. >            for (j=0; j <= tests-1; j=j+1)
  42. >            {
  43. >                gets(&scores[i][j];
  44.  
  45. 1) "scores" is an array of STUDENT arrays of 5 chars, so 
  46.    "scores[i][j]" is _one_ char. The only string that
  47.    can be stored in _one_ char is the empty string.
  48.  
  49. 2) Don't use gets(), use fgets() to check that the users 
  50.    really enters an empty string:
  51.  
  52.       fgets(&scores[i][j], 1, stdin);
  53.  
  54.    This will not allow much user interaction in most implementations,
  55.    btw.
  56.  
  57. 3) Maybe you want to allow nonempty input. One way to do this
  58.    is
  59.  
  60.    #include <stdlib.h>
  61.    #include <string.h>
  62.  
  63.    char *scores[STUDENT][5];
  64.  
  65.    and inside your inner loop:
  66.  
  67.                   char tmp[A_BIG_NUMBER], *newline;
  68.  
  69.                   fgets(tmp, sizeof tmp, stdin);
  70.                   newline = strchr(tmp, '\n');
  71.                   if (newline) 
  72.                      *newline = '\0';
  73.                   else 
  74.                      /* die */;
  75.                   scores[i][j] = malloc(strlen(tmp) + 1);
  76.                   if (scores[i][j])
  77.                      strcpy(scores[i][j], tmp);
  78.                   else
  79.                      /* die */
  80.  
  81. >            }
  82. >        }
  83.  
  84. >I print out the scores in the same type of loop structure:
  85.  
  86. >    for (i=0; i <= students-1; i=i+1)
  87. >        {
  88. >        printf("Scores for student %d",i+1);
  89. >            for (j=0; j <= tests-1; j=j+1)
  90. >            {
  91. >                printf("\tGrade %d: %s",j+1,scores[i][j]);
  92.                                              ^^^^^^ ???
  93. >            }
  94. >        }
  95.  
  96. >I am getting (if you don't already know this):
  97.  
  98. I did not expect this, and I don't belief it, either. At the position
  99. marked with (???), your compiler inserts the magical address of operator,
  100. not available in most implementations of C that I know. You promised
  101. to pass a pointer to char to printf(), but you really passed an int.
  102. If that int holds the address (remember that transformation of an
  103. int to a pointer is defined only for one constant value) of the char
  104. that was passed to printf() as an int, real magic is at work.
  105.  
  106. >        Scores for student 1: Grade 1: 999991   Grade 2: 99991   Grade
  107. >3: 9991    Grade 4: 991    Grade 5: 91
  108.  
  109. This is the expected output for "&scores[i][j]".
  110.  
  111. >Is my data being mangled some how in the data entry? I've tried just
  112. >printing out 1 array element or not using the loop and naming each
  113. >element but nothing seems to work.
  114.  
  115. If your user does not enter an empty string for the last grade of the
  116. last student, or a string of more than one char for the last but one
  117. grade of the last student, of a string of more than two chars for the
  118. last but two grade of the last student, etc., you are going to write
  119. to memory that does not belong to you. I dont know about the grading
  120. system in your country, but if grades can have more than zero digits,
  121. you are going to write to memory that you dont want to write to most
  122. of the time. If grades are one digit entities, adding one extra 
  123. student and _not_ treating the elements of "scores" as strings might
  124. "work", but it is still very _bad_ practice.
  125.  
  126. Kurt
  127. --  
  128. | Kurt Watzka                             Phone : +49-89-2180-6254
  129. | watzka@stat.uni-muenchen.de
  130.